/**
 * 使用两个栈模拟队列
 * s1出栈用作出队列，若s2为空，则先将s1的所有元素送入s2
 * s1入栈用作入队列，若s1为满，则先保证s2为空，才能将s1的元素送入s2
 */

#include "stack/stack.h"

/**
 * 判断栈是否为满
 */
bool StackOverflow(SqStack *s)
{
    if (s->top == STACK_MAX_SIZE - 1)
    {
        return true;
    }
    return false;
}

/**
 *
 * @param s1 栈1，用来入队
 * @param s2 栈2，用来出队
 * @param e 将要入队列的元素
 */
int enQueue(SqStack *s1, SqStack *s2, int e)
{
    if (!StackOverflow(s1))//s1不满，直接插入
    {
        pushStack(s1, e);
        return 1;
    }
    //s1满了，但是s2不空，此时队列满了，只能出队列
    //这里数据结构没有占满。但是我们只能以这种方式来“定义”满了
    //否则就会导致queue的先进后出特性被破坏
    if (StackOverflow(s1) && !stackEmpty(s2))
    {
        printf("queue full\n");
        return 0;
    }
    //s1满，s2空的时候，将s1的元素都搬到s2中，从而时s2取数据与元素到来的顺序一致
    if (StackOverflow(s1) && stackEmpty(s2))
    {
        while (!stackEmpty(s1))
        {
            int *x;
            popStack(s1, x);
            pushStack(s2, *x);
        }
    }
    pushStack(s1, e);
    return 1;
}

void deQueue(SqStack *s1, SqStack *s2, int *x)
{
    if (!stackEmpty(s2))//s2非空，则直接输出
    {
        popStack(s2, x);
    }
    else if (stackEmpty(s1))//s2空，s1为空，则无元素，队列为空
    {
        printf("queue empty\n");
    }
    else//s2空，但是s1非空
    {
        while (!stackEmpty(s1))//将s1的所有元素搬到s2中，从而可以输出
        {
            popStack(s1, x);
            pushStack(s2, x);
        }
        popStack(s2, x);
    }
}

int queueEmpty(SqStack s1, SqStack s2)
{
    if (stackEmpty(&s1) && stackEmpty(&s2))
    {
        return 1;
    }
    return 0;
}